package uk.ac.lkl.lpp.ui;



import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.text.NumberFormat;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import uk.ac.lkl.common.associator.Associator;
import uk.ac.lkl.common.associator.event.AssociatorAdapter;
import uk.ac.lkl.common.associator.event.AssociatorEvent;
import uk.ac.lkl.common.ui.Editor;
import uk.ac.lkl.common.util.ds.NotifyingMap;
import uk.ac.lkl.common.util.ds.event.MapEvent;
import uk.ac.lkl.common.util.ds.event.MapListener;
import uk.ac.lkl.lpp.model.PedagogyPlanModel;



import uk.ac.lkl.lpp.model.ldo.CognitiveActivity;
import uk.ac.lkl.lpp.model.ldo.TeachingMethod;



public class TeachingMethodEditor extends Editor<TeachingMethod> {

    /**
     * Need this so can get associations, etc.
     * 
     */
    private PedagogyPlanModel model;

    private NotifyingMap<TeachingMethod, Float> hoursMap;

    private Associator<TeachingMethod, Float, CognitiveActivity> cognitiveActivityMap;

    private JTextField hoursField = new JTextField(3);

    // hack: same as in table. Re-use this code
    private static NumberFormat FORMAT;

    static {
        FORMAT = NumberFormat.getNumberInstance();
        FORMAT.setMaximumFractionDigits(1);
        FORMAT.setMinimumFractionDigits(0);
    }


    public TeachingMethodEditor(PedagogyPlanModel model,
            TeachingMethod teachingMethod) {
        super(teachingMethod);
        this.model = model;
        initialiseData();
        addListeners();
        setModel(teachingMethod);
        initialiseLayout();
    }


    public void updateView() {
        updateHoursField();
    }


    @Override
    protected void updateData() {

    }


    private void initialiseData() {
        hoursMap = model.getMap(
                                "TeachingMethodHoursAllocation",
                                TeachingMethod.class,
                                Float.class);
        cognitiveActivityMap = model.getAssociator(
                                                   TeachingMethod.class,
                                                   Float.class,
                                                   CognitiveActivity.class);

    }


    private void addListeners() {
        addHoursListener();
        addCognitiveActivityListener();
    }


    private void addHoursListener() {
        hoursMap.addMapListener(new MapListener<TeachingMethod, Float>() {

            public void entryAdded(MapEvent<TeachingMethod, Float> e) {
                // assume doesn't happen
            }


            public void entryRemoved(MapEvent<TeachingMethod, Float> e) {
                // assumes doesn't happen
            }


            public void valueChanged(MapEvent<TeachingMethod, Float> e) {
                TeachingMethod eventTeachingMethod = e.getKey();
                if (eventTeachingMethod != getModel())
                    return;
                Float newValue = e.getNewValue();
                updateHoursField(newValue);
            }
        });
    }


    private void addCognitiveActivityListener() {
        cognitiveActivityMap
                .addAssociatorListener(new AssociatorAdapter<TeachingMethod, Float, CognitiveActivity>() {

                    public void annotationChanged(AssociatorEvent<TeachingMethod, Float, CognitiveActivity> e) {
                        TeachingMethod eventTeachingMethod = e.getLeftElement();
                        if (eventTeachingMethod != getModel())
                            return;
                        Float annotation = e.getAnnotation();
                        // todo: update appropriate element
                    }

                });
    }


    /**
     * 
     * 
     */
    private void updateHoursField() {
        Float hours = hoursMap.get(getModel());
        updateHoursField(hours);
    }


    private void updateHoursField(Float value) {
        if (value == null)
            hoursField.setText("");
        else
            hoursField.setText(FORMAT.format(value));
    }


    private void initialiseLayout() {
        JPanel overheadsPanel = createOverheadsPanel();
        add(new JLabel(getModel().getTitle()));
        add(hoursField);
    }


    private JPanel createOverheadsPanel() {
        JPanel panel = new JPanel();
        GridBagLayout layout = new GridBagLayout();
        panel.setLayout(layout);
        GridBagConstraints c = new GridBagConstraints();

        // addOverheadLine(0,

        c.gridx = 0;
        c.gridy = 0;

        return panel;
    }

}
